/*
 cluster_gen.cpp
 Matthew Jee
 mcjee@ucsc.edu
*/

#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include "types.h"
#include "clustering.h"
#include "debug.h"
#include "io.h"

using namespace std;

/* General Settings */
double _epsilon;
size_t _minPoints;
bool _useDistanceCache;

/* Rendering */
#pragma mark -
#pragma mark Rendering

void clusterPaths(vector<mj::Path> &paths) {
    // setup circle renderables
    vector<mj::Cluster> clusters;
    if (_useDistanceCache) {
        cerr << "Creating Distance Cache" << endl;
        mj::initPathDistanceCache(paths);
        cerr << "clustering" << endl;
        clusters = mj::clusterPathsDBSCAN(paths, _minPoints, _epsilon, mj::pathDistanceAlignFrontCached);
        cerr << "Clearing Distance Cache" << endl;
        mj::clearPathDistanceCache();
    } else {
        cerr << "clustering" << endl;
        clusters = mj::clusterPathsDBSCAN(paths, _minPoints, _epsilon, mj::pathDistanceAlignFront);
    }
    
    writeClusters(cout, clusters);
}

/* Main */
#pragma mark -
#pragma mark Main

int main(int argc, char **argv) {

    if (argc < 3) {
        cerr << "usage: cluster_gen epsilon minPts [useDistanceCache]" << endl;
        return 1;
    }

    _epsilon = atof(argv[1]);
    _minPoints = atol(argv[2]);
    _useDistanceCache = argc >= 4 ? string(argv[3]) == "true": false;

    vector<mj::Path> paths = readTraclusPaths(cin);
    clusterPaths(paths);

    return 0;
}
